//package com.example.springai.controller;
//
//import com.example.springai.config.AIConfig;
//import com.example.springai.config.ChatRequest;
//import com.example.springai.config.ChatRequestExample;
//import com.example.springai.function.MockWeatherService;
//import com.example.springai.school.SchoolQueryTools;
//import com.fasterxml.jackson.core.JsonProcessingException;
//import com.fasterxml.jackson.databind.ObjectMapper;
//import org.springframework.ai.chat.client.ChatClient;
//import org.springframework.ai.chat.messages.Message;
//import org.springframework.ai.chat.messages.SystemMessage;
//import org.springframework.ai.chat.messages.UserMessage;
//import org.springframework.ai.chat.model.ChatResponse;
//import org.springframework.ai.chat.prompt.Prompt;
//import org.springframework.ai.document.Document;
//import org.springframework.ai.model.ModelOptionsUtils;
//import org.springframework.ai.model.function.FunctionCallback;
////import org.springframework.ai.model.function.FunctionCallbackWrapper;
//import org.springframework.ai.model.tool.ToolCallingChatOptions;
//import org.springframework.ai.openai.OpenAiChatModel;
//import org.springframework.ai.openai.OpenAiChatOptions;
//import org.springframework.ai.openai.api.OpenAiApi;
//import org.springframework.ai.openai.api.ResponseFormat;
//import org.springframework.ai.vectorstore.SearchRequest;
//import org.springframework.ai.vectorstore.VectorStore;
//import org.springframework.ai.vectorstore.filter.Filter;
//import org.springframework.ai.vectorstore.filter.FilterExpressionBuilder;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.beans.factory.annotation.Qualifier;
//import org.springframework.http.ResponseEntity;
//import org.springframework.util.StringUtils;
//import org.springframework.web.bind.annotation.GetMapping;
//import org.springframework.web.bind.annotation.RequestParam;
//import org.springframework.web.bind.annotation.RestController;
//import reactor.core.publisher.Flux;
//
//import java.lang.reflect.InvocationTargetException;
//import java.lang.reflect.Method;
//import java.util.*;
//import java.util.concurrent.atomic.AtomicBoolean;
//import java.util.stream.Collectors;
//
//@RestController
//public class OpenaiController {
//
//    @Autowired
//    private OpenAiChatModel openAiChatModel;
//    @Autowired
//    AIConfig chatRequestBean;
//    @GetMapping(value = "/openai/generateStream", produces = "text/html;charset=UTF-8")
//    public Flux<String> generateStream(@RequestParam(value = "message", defaultValue = "给我讲一个笑话") String message) {
////        openAiChatModel。
//        List<Message> messageList = Arrays.asList(new SystemMessage("请全部用简体中文回答"), new UserMessage(message));
//        Prompt prompt = new Prompt(messageList);
//
//        return openAiChatModel.stream(prompt).map((r) -> r.getResult() != null && r.getResult().getOutput() != null && r.getResult().getOutput().getText() != null ? r.getResult().getOutput().getText() : "").filter(StringUtils::hasLength);
//    }
//    @GetMapping(value = "/openai/functionCalling", produces = "text/html;charset=UTF-8")
//    public String functionCalling(@RequestParam(value = "message", defaultValue = "今天的热点新闻有哪些") String message) {
//
//
//        ChatResponse response = this.openAiChatModel.call(new Prompt(new SystemMessage(message),
//                OpenAiChatOptions.builder().function("hotNews").build()));
//        String content = response.getResult().getOutput().getText();
//        System.out.println("content = " + content);
//        return content;
////        return openAiChatModel.call(prompt).getResult().getOutput().getContent();
//    }
//
//    @GetMapping(value = "/openai/functionCalling/v1", produces = "text/html;charset=UTF-8")
//    public String functionCallingv1(@RequestParam(value = "message", defaultValue = "今天西安温度多少度?") String message) {
//        UserMessage userMessage = new UserMessage(message);
////        new Prompt(userMessage,
////                OpenAiChatOptions.builder().function("CurrentWeather").build());
////        this.openAiChatModel
//
//        Method method = null;
//        try {
//            method = OpenAiChatModel.class.getDeclaredMethod("createRequest", Prompt.class, boolean.class);
//            method.setAccessible(true);
//            OpenAiApi.ChatCompletionRequest currentWeather = (OpenAiApi.ChatCompletionRequest) method.invoke(openAiChatModel, new Prompt(userMessage,
//
//                    OpenAiChatOptions.builder().responseFormat(ResponseFormat.builder()
//
//                                    .type(ResponseFormat.Type.TEXT)
//                                    .build())
//                            .functions(Set.of("queryMajorCount", "queryCollegeCount", "queryHotSchool"))// Enable the function
//                            .build()), false);
//            List<OpenAiApi.FunctionTool> tools = currentWeather.tools();
//
//            Map<String, FunctionCallback> functionCallbackRegister = openAiChatModel.getFunctionCallbackRegister();
//            functionCallbackRegister.forEach((key, value) -> {
//                value.call("""
//                        {"schoolName":"清华大学"}
//                        """);
//
//            });
//
//            System.out.println("functionCallbackRegister = " + functionCallbackRegister);
//
////            System.out.println("tools = " + tools);
//            ObjectMapper objectMapper = new ObjectMapper();
//            String toolsJson = objectMapper.writeValueAsString(tools);
//            System.out.println("Tools JSON: " + toolsJson);
//
//        } catch (NoSuchMethodException e) {
//            throw new RuntimeException(e);
//        } catch (InvocationTargetException e) {
//            throw new RuntimeException(e);
//        } catch (IllegalAccessException e) {
//            throw new RuntimeException(e);
//        } catch (JsonProcessingException e) {
//            throw new RuntimeException(e);
//        }
//
//        // 设置方法可访问
//
//
//        // 调用方法
//
//        ChatResponse response = this.openAiChatModel.call(new Prompt(userMessage,
//                OpenAiChatOptions.builder().responseFormat(ResponseFormat.builder()
//
//                                .type(ResponseFormat.Type.TEXT)
//                                .build())
//                        .functions(Set.of("CurrentWeather"))// Enable the function
//                        .build())); // Enable the function
//        String content = response.getResult().getOutput().getText();
////        logger.info("Response: {}", response);
//
//        return content;
//
//    }
//
//    @GetMapping(value = "/openai/functionCalling/v2", produces = "text/html;charset=UTF-8")
//    public Flux<String> functionCallingv2(@RequestParam(value = "message", defaultValue = "What's the weather like in San Francisco, Tokyo, and Paris?") String message) {
//
//
//        UserMessage userMessage = new UserMessage("获取西安的天气信息");
//        //TODO: 后期这里需要查询数据库
//        var promptOptions = OpenAiChatOptions.builder()
//
//                .functionCallbacks(List.of(FunctionCallback.builder()
//                        .function("CurrentWeather", new MockWeatherService())
//                        // (1) function name and instance
//                        .description("获取所在位置的天气信息") // (2) function description
//                        .inputType(MockWeatherService.Request.class)
//
//                        // (3) function input type
//                        .build())) // function code
//                .build();
//        System.out.println("Function callbacks: " + promptOptions.getFunctionCallbacks());
//
//        Prompt prompt = new Prompt(userMessage, promptOptions);
//        return openAiChatModel.stream(prompt)
//                .map(r -> r.getResult() != null && r.getResult().getOutput() != null && r.getResult().getOutput().getText() != null
//                        ? r.getResult().getOutput().getText()
//                        : "")
//                .filter(StringUtils::hasLength)
//                .doOnError(error -> {
//                    System.err.println("Error occurred during streaming: " + error);
//                    // Additional error handling if necessary
//                })
//                .doOnComplete(() -> System.out.println("Streaming completed"));
//    }
//
//    @Autowired
//    private SchoolQueryTools schoolQueryTools;
//
//    @GetMapping(value = "/openai/functionCalling/v3", produces = "text/html;charset=UTF-8")
//    public String functionCallingv3(@RequestParam(value = "message", defaultValue = "What's the weather like in Paris?") String message) {
//
//        List<Map<String, Object>> messages = new ArrayList<>();
//        messages.add(Map.of(
//                "role", "user",
//                "content", "杭州今天多少度?"
//        ));
//
//        String response = OpenAIClient.sendMessages(messages);
//        System.out.println("Response: " + response);
//
//        // 打印对话内容
//        for (Map<String, Object> msg : messages) {
//            System.out.println(msg.get("role").toString().toUpperCase() + "> " + msg.get("content"));
////        UserMessage userMessage = new UserMessage(message);
////
////        ChatResponse response = this.openAiChatModel.call(new Prompt(userMessage,
////                OpenAiChatOptions.builder().function("CurrentWeather").build())); // Enable the function
////        String content = response.getResult().getOutput().getContent();
////        logger.info("Response: {}", response);
////        System.out.println("content = " + content);
//
//
//        }
//        return response;
//    }
//
//    @GetMapping(value = "/openai/functionCallingSchool/v1", produces = "text/html;charset=UTF-8")
//    public String functionCallingSchoolv1(@RequestParam(value = "message", defaultValue = "北大有多少个专业?") String message) {
////        UserMessage userMessage = new UserMessage(message);
//        List<Message> messageList = Arrays.asList(new SystemMessage("你是一个大学查询系统。请全部用简体中文回答,大学用全名"), new UserMessage(message));
//
////        new Prompt(userMessage,
////                OpenAiChatOptions.builder().function("CurrentWeather").build());
////        openAiChatModel.getFunctionCallbackRegister()
////        openAiChatModel.createRequest(new Prompt(messageList), false);
////        OpenAiChatOptions.Builder tools = OpenAiChatOptions.builder().tools(this);
//        ChatResponse response = this.openAiChatModel
//                .call(new Prompt(messageList,
//                        OpenAiChatOptions.builder()
//                                .responseFormat(ResponseFormat.builder()
//                                        .type(ResponseFormat.Type.TEXT)
//                                        .build())
//                                .toolNames(Set.of("queryMajorCount", "queryCollegeCount", "queryHotSchool", "addSchool"))// Enable the function
//                                .build())); // Enable the function
//
//        String content = response.getResult().getOutput().getText();
//        System.out.println("response = " + response);
////        logger.info("Response: {}", response);
//        response.getResult().getOutput().getToolCalls().forEach(toolCall -> {
//            System.out.println("Tool call: " + toolCall);
//        });
//        System.out.println("content = " + content);
//        return content;
//
//    }
//
//    @GetMapping(value = "/openai/functionCallingSchoolv2/v1", produces = "text/html;charset=UTF-8")
//    public String functionCallingSchoolv2(@RequestParam(value = "message", defaultValue = "北京今天温度多少") String message) {
////        UserMessage userMessage = new UserMessage(message);
//        List<Message> messageList = Arrays.asList(new SystemMessage("请全部用简体中文回答,大学用全名（不需要执行函数，只需要将执行的函数返回即可）"), new UserMessage(message));
//
////        new Prompt(userMessage,
////                OpenAiChatOptions.builder().function("CurrentWeather").build());
//        var functionTool = new OpenAiApi.FunctionTool(OpenAiApi.FunctionTool.Type.FUNCTION,
//                new OpenAiApi.FunctionTool.Function("Get the weather in location. Return temperature in Celsius.",
//                        "getCurrentWeather", ModelOptionsUtils.jsonToMap("""
//                        {
//                        	"type": "object",
//                        	"properties": {
//                        		"location": {
//                        			"type": "string",
//                        			"description": "获取所在位置的天气信息。返回温度（摄氏度）。"
//                        		},
//                        		"lat": {
//                        			"type": "number",
//                        			"description": "The city latitude"
//                        		},
//                        		"lon": {
//                        			"type": "number",
//                        			"description": "The city longitude"
//                        		},
//                        		"unit": {
//                        			"type": "string",
//                        			"enum": ["C", "F"]
//                        		}
//                        	},
//                        	"required": ["location", "lat", "lon", "unit"]
//                        }
//                        """), false));
//        ChatResponse response = this.openAiChatModel.call(new Prompt(messageList,
//                OpenAiChatOptions.builder().tools(List.of())
//                        .responseFormat(ResponseFormat.builder()
//                                .type(ResponseFormat.Type.TEXT)
//                                .build())
//                        // Enable the function
//                        .build())); // Enable the function
//        String content = response.getResult().getOutput().getText();
//        System.out.println("response = " + response);
////        logger.info("Response: {}", response);
//        response.getResult().getOutput().getToolCalls().forEach(toolCall -> {
//            System.out.println("Tool call: " + toolCall);
//        });
//        System.out.println("content = " + content);
//        return content;
//
//    }
//
//    @GetMapping(value = "/deepseek/functionCalling/v3")
//    public Map<String, String> functionCallingv31(@RequestParam(value = "message", defaultValue = "展示最新的OFFER?") String message) {
//        UserMessage userMessage = new UserMessage(message);
//        final String[] body1 = new String[1];
//        Map<String, String> bodyMap = new HashMap<>();
//        body1[0] = "系统出现BUG，请稍后再试";
//        ChatRequest.Message system = new ChatRequest.Message("system", "你是公司内部的AI助手用户提问的内容，如果和函数无关，请不要调用函数，请格式化输出内容到html的<body>标签中");
//        ChatRequest.Message user = new ChatRequest.Message("user", message);
//        try {
//
//            OpenAiApi.ChatCompletionRequest currentWeather =  chatRequestBean.createChatRequestFunction1();
//            List<OpenAiApi.FunctionTool> tools = currentWeather.tools();
//
//            org.springframework.http.ResponseEntity<OpenAiApi.ChatCompletion> chatCompletionChunkResponseEntity = ChatRequestExample.requestDeepSeekChat(tools, List.of(system, user));
//
//            ToolCallingChatOptions toolCallingChatOptions = chatRequestBean.getToolCallingChatOptions();
//
//            List<FunctionCallback> functionCallbacks = toolCallingChatOptions.getToolCallbacks();
//            Map<String, FunctionCallback> functionCallbackRegister = functionCallbacks.stream()
//                    .collect(Collectors.toMap(FunctionCallback::getName, functionCallback -> functionCallback));
//            OpenAiApi.ChatCompletion body = chatCompletionChunkResponseEntity.getBody();
//            if (body != null) {
//                {
//                    List<OpenAiApi.ChatCompletionMessage.ToolCall> toolCalls = body.choices().get(0).message().toolCalls();
//                    if (toolCalls == null || toolCalls.isEmpty()) {
//                        body1[0] = body.choices().get(0).message().content();
//
//                        bodyMap.put("content", body1[0]);
//                        return bodyMap;
//                    }
//                    body.choices().forEach(choice -> {
//
//                        List<OpenAiApi.ChatCompletionMessage.ToolCall> toolCalls1 = choice.message().toolCalls();
//
//                        //TODO 管理添加的功能，需要人工二次确认才可行
//                        Iterator<OpenAiApi.ChatCompletionMessage.ToolCall> iterator = toolCalls1.iterator();
//                        while (iterator.hasNext()) {
//                            OpenAiApi.ChatCompletionMessage.ToolCall toolCall = iterator.next(); // 获取当前元素
//                            FunctionCallback functionCallback = functionCallbackRegister.get(toolCall.function().name());
//                            String call = functionCallback.call(toolCall.function().arguments());
//                            // 如果不是最后一个元素，继续迭代
//                            if (iterator.hasNext()) {
//
//                            } else {
//                                // 如果是最后一个元素，执行额外的逻辑
//                                ResponseEntity<OpenAiApi.ChatCompletion>
//                                        chatCompletionChunkResponseEntity1 = ChatRequestExample.requestDeepSeekChat(null, List.of(
//                                        system,
//                                        user,
//                                        new ChatRequest.Message("user", call)
//                                ));
//                                body1[0] = chatCompletionChunkResponseEntity1.getBody().choices().get(0).message().content();
//                                bodyMap.put("content", body1[0]);
//                            }
//                        }
//                    });
//                }
//            }
//            return bodyMap;
//        } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
//            throw new RuntimeException(e);
//        } catch (Exception e) {
//            throw new RuntimeException(e);
//        }
//
//    }
//    @Autowired
//    @Qualifier("neo4jVectorStore")
//    private VectorStore vectorStore;
//
//    @GetMapping("/add")
//    public List<Document> addDocuments() {
//        List<Document> documents = List.of(
//
//                new Document("我是一个美国人", Map.of("nationality", "美国","year1",2025))
//            );
//
//// 将文档列表添加到 Redis 中
//// 文档内容会通过嵌入模型生成向量，并存储到 Redis 向量存储中
//        vectorStore.add(documents);
//        FilterExpressionBuilder b = new FilterExpressionBuilder();
//        Filter.Expression expression = b.eq("year1", 2025).build();
//
//        List<Document> spring = this.vectorStore.similaritySearch(
//                SearchRequest.builder().query("2025").topK(5).filterExpression(expression).build());
//
//        Document document = spring.get(0);
//
//        System.out.println("document = " + document);
//        document.getMetadata().forEach((k, v) -> {
//            System.out.println("k = " + k + " v = " + v);
//        });
//        return spring;
//    }
//}
